package com.levi.async;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author shentong
 * @since 2022/1/13 9:20 PM
 * ExecutorCompletionService返回结果的顺序是有序的，按照线程执行的顺序返回结果，因为把任务的执行都放进了队列中
 * 按照队列中的顺序依次执行
 */
public class CompletionServiceDemo {
    //创建用于执行任务的线程池
    static ExecutorService executorService = Executors.newFixedThreadPool(10);

    public static void main(String[] args) {
        List<Future<Integer>> futures = new ArrayList<>();
        ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);
        //submit提交的任务都放进了队列中
        Future<Integer> futureA = completionService.submit(new CalculateArticleScoreA());
        Future<Integer> futureB = completionService.submit(new CalculateArticleScoreB());
        Future<Integer> futureC = completionService.submit(new CalculateArticleScoreC());
        futures.add(futureA);
        futures.add(futureB);
        futures.add(futureC);
        int sum = 0;
//        for (int i = 0; i < 3; i++) {
//            try {
//                sum += completionService.take().get();
//            } catch (InterruptedException | ExecutionException e) {
//                e.printStackTrace();
//            }
//        }
        for (Future<Integer> future : futures) {
            try {
                sum += future.get();
            } catch (InterruptedException | ExecutionException e) {
                future.cancel(true);
                e.printStackTrace();
            }
        }
        executorService.shutdown();
        System.out.println("求和是："+sum);
    }


    private static class CalculateArticleScoreA implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            TimeUnit.SECONDS.sleep(2);
            System.out.println(Thread.currentThread().getName());
            return 1;
        }
    }

    private static class CalculateArticleScoreB implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            TimeUnit.SECONDS.sleep(4);
            System.out.println(Thread.currentThread().getName());
            return 2;
        }
    }

    private static class CalculateArticleScoreC implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            TimeUnit.SECONDS.sleep(6);
            System.out.println(Thread.currentThread().getName());
            return 3;
        }
    }


}
